package com.site.common.context;


import org.springframework.context.ApplicationContext;
import org.springframework.util.Assert;
 
/**
 * 以静态变量保存Spring ApplicationContext,可在任意代码中取出ApplicaitonContext.
 * 
 * 这个类也应用了单例模式
 * 
 * @author 刘圳
 * @date 2009-12-8
 * @version $Revision$
 * @see PropsLoader
 */
public class SpringContextHolder {

	private SpringContextHolder() {
	}

	private static final SpringContextHolder instance = new SpringContextHolder();

	private ApplicationContext applicationContext;

	private ApplicationContext getApplicationContextImpl() {
		checkApplicationContext();
		return applicationContext;
	}

	private void setApplicationContextImpl(ApplicationContext applicationContext) {
		Assert.notNull(applicationContext, "applicationContext不能为空");
		this.applicationContext = applicationContext;
	}

	private Object getBeanImpl(String name) {
		checkApplicationContext();
		return applicationContext.getBean(name);
	}

	private <T> T getBeanImpl(Class<T> requiredType) {
		checkApplicationContext();
		return applicationContext.getBean(requiredType);
	}

	private void checkApplicationContext() {
		if (applicationContext == null)
			throw new IllegalStateException(
					"applicaitonContext未注入,请在applicationContext.xml中定义SpringContextUtil");
	}

	/**
	 * 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量.
	 */
	public static void setApplicationContext(ApplicationContext applicationContext) {
		instance.setApplicationContextImpl(applicationContext);
	}

	/**
	 * 取得存储在静态变量中的ApplicationContext.
	 */
	public static ApplicationContext getApplicationContext() {
		return instance.getApplicationContextImpl();
	}

	/**
	 * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getBean(String name) {
		return (T) instance.getBeanImpl(name);
	}

	public static <T> T getBean(Class<T> requiredType) {
		return instance.getBeanImpl(requiredType);
	}

}
